package sdu.icat.forum.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.transaction.Transactional;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import sdu.icat.forum.repository.ForumCommentInfoRepository;
import sdu.icat.forum.repository.ForumCommentRepository;
import sdu.icat.forum.repository.ForumDocumentInfoRepository;
import sdu.icat.forum.repository.ForumDocumentRepository;
import sdu.icat.forum.repository.ForumReplyRepository;
import sdu.icat.forum.smodel.ForumComment;
import sdu.icat.forum.smodel.ForumCommentInfo;
import sdu.icat.forum.smodel.ForumDocument;
import sdu.icat.forum.smodel.ForumDocumentInfo;
import sdu.icat.forum.smodel.ForumReply;
import sdu.icat.pj.support.SimpleSpecification;

@Service(value="forum_document_service")
public class ForumDocumentService {

    private final Logger logger = LogManager.getLogger();

    @Autowired private ForumDocumentRepository forumDocumentRepository;

    @Autowired private ForumDocumentInfoRepository forumDocumentInfoRepository;

    @Autowired private ForumCommentRepository forumCommentRepository;

    @Autowired private ForumCommentInfoRepository forumCommentInfoRepository;

    @Autowired private ForumReplyRepository forumReplyRepository;

    @Transactional
    public Page<ForumDocument> getAllForumDocument(int page,int size,Map<String,Object> params) {
	Sort sort = new Sort(Direction.ASC,"id");
	PageRequest pageable = new PageRequest(page,size,sort); 
	return forumDocumentRepository.findAll(new SimpleSpecification<ForumDocument>(params, ForumDocument.class),pageable);
    }

    @Transactional
    public Map<String,Object> ForumDocumentDetail(Long documentid,int page,int size) {
	Map<String,Object> result = new HashMap<>();
	Sort sort = new Sort(Direction.ASC,"id");
	PageRequest pageable = new PageRequest(page,size,sort);
	ForumDocument document = forumDocumentRepository.findOne(documentid);
	result.put("document", document);
	Page<ForumComment> comments = forumCommentRepository.findAll(pageable);
	result.put("comment", comments);
	for(ForumComment comment:comments.getContent()) {
	    List<ForumReply> replys = forumReplyRepository.findByCommentId(comment.getId());
	    result.put("reply_"+comment.getId(), replys);
	}
	return result;
    }

    @Transactional
    public List<ForumReply> ForumCommentDetail(Long commentid) {
	return forumReplyRepository.findByCommentId(commentid);
    }

    public void addComment(long documentid,int replyNum,int readNum,int goodNum) {
	ForumDocumentInfo documentinfo = forumDocumentInfoRepository.findByDocumentId(documentid);
	if(documentinfo==null) {
	    documentinfo = new ForumDocumentInfo();
	    documentinfo.setDocumentId(documentid);
	}
	int rpcount = documentinfo.getReplyCount()+replyNum;
	int rncount = documentinfo.getReadCount()+readNum;
	int gdcount = documentinfo.getGoodCount()+goodNum;
	documentinfo.setReplyCount(rpcount);
	documentinfo.setReadCount(rncount);
	documentinfo.setGoodCount(gdcount);
	//修改数据
	forumDocumentInfoRepository.save(documentinfo);
    }

    public void addReply(long commentid,int replyNum) {
	ForumCommentInfo fci = forumCommentInfoRepository.findByCommentId(commentid);
	if(fci==null) {
	    fci = new ForumCommentInfo();
	    fci.setCommentId(commentid);
	}
	int count = fci.getReplyCount()+replyNum;
	fci.setReplyCount(count);
	forumCommentInfoRepository.save(fci);
    }

    /**
     * 发表帖子
     */
    @Transactional
    public void publishDocument(ForumDocument forumDocument) {
	forumDocumentRepository.save(forumDocument);
    }

    /**
     * 根据帖子发表回复
     * @param documentid
     * @param comment
     */
    @Transactional
    public void publishComment(long documentid,ForumComment comment) {
	Assert.notNull(comment, "NULL COMMENT PARAMETER");
	forumCommentRepository.save(comment);
	addComment(documentid, 1, 0, 0);
    }

    @Transactional
    public void publishReply(long commentid,ForumReply reply) {
	Assert.notNull(reply, "NULL REPLY");
	ForumComment comment = forumCommentRepository.findOne(commentid);
	addComment(comment.getDocumentId(), 1, 0, 0);
	addReply(commentid, 1);
	forumReplyRepository.save(reply);
    }

    /**
     * 删除，将文章状态置为3
     * @param documentid
     */
    @Transactional
    public boolean deleteDocument(long documentid) {
	ForumDocument document = forumDocumentRepository.findOne(documentid);
	if(document!=null) {
	    document.setStatus(3);
	    forumDocumentRepository.save(document);
	    return true;
	}
	return false;
    }

    @Transactional
    public int deleteDocument(long[] documentids) {
	for(int i=0;i<documentids.length;i++) {
	    try {
		deleteDocument(documentids[i]);
	    } catch (Exception e) {
		return 0;
	    }
	}
	return documentids.length;
    }

    /**
     * 恢复,将文章状态置为4
     * @param documentid
     * @return
     */
    @Transactional
    public boolean recoverDocument(long documentid) {
	ForumDocument document = forumDocumentRepository.findOne(documentid);
	if(document!=null) {
	    document.setStatus(4);
	    forumDocumentRepository.save(document);
	    return true;
	}
	return false;
    }

    /**
     * 批量恢复
     * @param commentids
     * @return
     */
    @Transactional
    public int recoverDocument(long[] documentids) {
	for(int i=0;i<documentids.length;i++) {
	    try {
		recoverDocument(documentids[i]);
	    } catch (Exception e) {
		return 0;
	    }
	}
	return documentids.length;
    }

    /**
     * 删除评论
     * @param commentid
     * @return
     */
    @Transactional
    public boolean deleteComment(long commentid) {
	ForumComment comment = forumCommentRepository.findOne(commentid);
	if(comment!=null) {
	    List<ForumReply> replys = forumReplyRepository.findByCommentId(commentid);
	    int count = replys.size()+1;
	    comment.setStatus(2);
	    addComment(comment.getDocumentId(), 0-count, 0, 0);
	    forumCommentRepository.save(comment);
	    return true;
	}
	return false;
    }

    /**
     * 批量删除
     * @param commentid
     * @return
     */
    @Transactional
    public int deleteComment(long[] commentids) {
	for(int i=0;i<commentids.length;i++) {
	    try {
		deleteComment(commentids[i]);
	    } catch (Exception e) {
		return 0;
	    }
	}
	return commentids.length;
    }

    /**
     * 批量恢复
     * @param commentids
     * @return
     */
    @Transactional
    public int recoverComment(long[] commentids) {
	for(int i=0;i<commentids.length;i++) {
	    try {
		recoverComment(commentids[i]);
	    } catch (Exception e) {
		return 0;
	    }
	}
	return commentids.length;
    }

    /**
     * 恢复评论
     * @param commentid
     * @return
     */
    @Transactional
    public boolean recoverComment(long commentid) {
	ForumComment comment = forumCommentRepository.findOne(commentid);
	if(comment!=null) {
	    List<ForumReply> replys = forumReplyRepository.findByCommentId(commentid);
	    int count = replys.size()+1;
	    comment.setStatus(3);
	    addComment(comment.getDocumentId(), count, 0, 0);
	    forumCommentRepository.save(comment);
	    return true;
	}
	return false;
    }


    /**
     * 删除评论里的回复
     * @param replyid
     * @return
     */
    public boolean deleteReply(long replyid) {
	ForumReply reply = forumReplyRepository.findOne(replyid);
	if(reply!=null) {
	    ForumComment fc = forumCommentRepository.findOne(reply.getCommentId());
	    addComment(fc.getDocumentId(), -1, 0, 0);
	    addReply(reply.getCommentId(), -1);
	    reply.setStatus(2);
	    forumReplyRepository.save(reply);
	    return true;
	}
	return false;
    }

    @Transactional
    public int deleteReply(long[] replyids) {
	for(int i=0;i<replyids.length;i++) {
	    try {
		deleteReply(replyids[i]);
	    } catch (Exception e) {
		return 0;
	    }
	}
	return replyids.length;
    }

    /**
     * 恢复评论里的回复
     * @param replyid
     * @return
     */
    @Transactional
    public boolean recoverReply(long replyid) {
	ForumReply reply = forumReplyRepository.findOne(replyid);
	if(reply!=null) {
	    ForumComment fc = forumCommentRepository.findOne(reply.getCommentId());
	    addComment(fc.getDocumentId(), 1, 0, 0);
	    addReply(reply.getCommentId(), 1);
	    reply.setStatus(3);
	    forumReplyRepository.save(reply);
	    return true;
	}
	return false;
    }

    @Transactional
    public int recoverReply(long[] replyids) {
	for(int i=0;i<replyids.length;i++) {
	    try {
		recoverReply(replyids[i]);
	    } catch (Exception e) {
		return 0;
	    }
	}
	return replyids.length;
    }


}
